//
//  JJVoiceHelper.m
//  swiftProject
//
//  Created by yangjian on 2021/12/6.
//

#import "JJVoiceRecordHelper.h"
#import "amrFileCodec.h"

//wav转mp3
//https://www.jianshu.com/p/e5938391bf52

static JJVoiceRecordHelper *jj = nil;
@interface JJVoiceRecordHelper ()<AVAudioRecorderDelegate>

@property (nonatomic, strong) NSDate *startDate;
@property (nonatomic, strong) NSDate *endDate;

@property (nonatomic, strong) AVAudioRecorder *recorder;
@property (nonatomic, strong) NSDictionary *recordSetting;

//录制的是wav格式,返回的是amr格式
@property (nonatomic, copy) void (^recordCompletion)(NSString *completePath, NSInteger duration);

@end

@implementation JJVoiceRecordHelper

+ (instancetype)shared{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        jj = [[self alloc] init];
    });
    return jj;
}
- (instancetype)init{
    self = [super init];
    if (self) {
        self.recordSetting = @{AVSampleRateKey:@(8000.0), AVFormatIDKey:@(kAudioFormatLinearPCM), AVLinearPCMBitDepthKey:@(16), AVNumberOfChannelsKey:@(1), AVEncoderAudioQualityKey:@(AVAudioQualityHigh)};
    }
    return self;
}

#pragma mark - Private


#pragma mark - AVAudioRecorderDelegate
- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder
                           successfully:(BOOL)flag {
    NSString *wavVoicePath = [[self.recorder url] path];
    if (!flag) {
        wavVoicePath = @"";
    }
    
    NSString *amrVoicePath = [wavVoicePath.stringByDeletingPathExtension stringByAppendingPathExtension:@"amr"];
    NSInteger duration = [[NSDate date] timeIntervalSinceDate:self.startDate];
    BOOL success = [self convertWAVtoAMR_wavPath:wavVoicePath amrPath:amrVoicePath];
    if (success) {
        //删除wav
        [NSFileManager.defaultManager removeItemAtPath:wavVoicePath error:nil];
    } else {
        wavVoicePath = nil;
        duration = 0;
    }
    if (self.recordCompletion) {
        self.recordCompletion(amrVoicePath, duration);
    }
    self.recorder = nil;
    self.recordCompletion = nil;
}

- (void)audioRecorderEncodeErrorDidOccur:(AVAudioRecorder *)recorder
                                   error:(NSError *)error{
    NSLog(@"-[JJVoiceHelper audioRecorderEncodeErrorDidOccur]");
}

#pragma mark - Private

- (void)_stopRecord
{
    _recorder.delegate = nil;
    if (_recorder.recording) {
        [_recorder stop];
    }
    _recorder = nil;
    self.recordCompletion = nil;
}

#pragma mark - Public

- (void)startRecord_path:(NSString *)path
              completion:(void(^)(NSError * _Nullable error))completion {
    NSError *error = nil;
    do {
        if (self.recorder && self.recorder.isRecording) {
            error = [NSError errorWithDomain:@"正在进行录制" code:-1 userInfo:nil];
            break;
        }
        AVAudioSessionRecordPermission permissionStatus = [[AVAudioSession sharedInstance] recordPermission];
        if (permissionStatus == AVAudioSessionRecordPermissionDenied) {
            error = [NSError errorWithDomain:@"未开启麦克风权限" code:-1 userInfo:nil];
            break;
        }
        [AVAudioSession.sharedInstance setCategory:AVAudioSessionCategoryPlayAndRecord
                                       withOptions:AVAudioSessionCategoryOptionDuckOthers
                                             error:&error];
        if (error) {
            error = [NSError errorWithDomain:@"AVAudioSession SetCategory失败" code:-1 userInfo:nil];
            break;
        }
        [[AVAudioSession sharedInstance] setActive:YES withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:&error];
        if (error) {
            error = [NSError errorWithDomain:@"AVAudioSession SetCategory失败" code:-1 userInfo:nil];
            break;
        }
        
        NSString *wavVoicePath = [[path stringByDeletingPathExtension] stringByAppendingPathExtension:@"wav"];
        NSURL *wavVoiceURL = [[NSURL alloc] initFileURLWithPath:wavVoicePath];
        self.recorder = [[AVAudioRecorder alloc] initWithURL:wavVoiceURL settings:self.recordSetting error:&error];
        
        if(error || !self.recorder) {
            self.recorder = nil;
            error = [NSError errorWithDomain:@"文件格式转换失败" code:-1 userInfo:nil];
            break;
        }
        BOOL success = [self.recorder prepareToRecord];
        if (!success) {
            [self _stopRecord];
            error = [NSError errorWithDomain:@"准备录制工作失败" code:-1 userInfo:nil];
            break;
        }
        self.startDate = [NSDate date];
        self.recorder.meteringEnabled = YES;
        self.recorder.delegate = self;
        success = [self.recorder record];
        if (!success) {
            [self _stopRecord];
            error = [NSError errorWithDomain:@"准备录制工作失败" code:-1 userInfo:nil];
            break;
        }
    } while (0);
    if (completion) {
        completion(error);
    }
}

-(void)stopRecord_completion:(void(^)(NSString *completePath, NSInteger duration))completion
{
    self.recordCompletion = completion;
    [self.recorder stop];
}

-(void)cancelRecord
{
    [self _stopRecord];
    self.startDate = nil;
    self.endDate = nil;
}


- (BOOL)convertWAVtoAMR_wavPath:(NSString *)wavPath amrPath:(NSString*)amrPath{
    BOOL success = NO;
    if ([NSFileManager.defaultManager fileExistsAtPath:amrPath]) {
        success = YES;
    } else if ([NSFileManager.defaultManager fileExistsAtPath:wavPath]) {
        audio_convertWAVEFileToAMRFile(wavPath.UTF8String, amrPath.UTF8String, 1, 16);
        if ([NSFileManager.defaultManager fileExistsAtPath:amrPath]) {
            success = YES;
        }
    }
    return success;
}

- (BOOL)convertAMRtoWAV_amrPath:(NSString*)amrPath wavPath:(NSString *)wavPath{

    BOOL success = NO;
    if ([NSFileManager.defaultManager fileExistsAtPath:wavPath]) {
        success = YES;
    } else if ([NSFileManager.defaultManager fileExistsAtPath:amrPath]) {
        audio_convertAMRFileToWAVEFile(amrPath.UTF8String, wavPath.UTF8String);
        if ([NSFileManager.defaultManager fileExistsAtPath:wavPath]) {
            success = YES;
        }
    }
    return success;
}


@end
